package com.vegetable.modules.service.wx.impl;

import com.vegetable.modules.service.wx.WxCpMessageService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.article.NewArticle;
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 企业微信消息推送服务实现
 *
 * @author Qoder
 */
@Slf4j
@Service
public class WxCpMessageServiceImpl implements WxCpMessageService {

    @Autowired
    private WxCpService wxCpService;

    @Value("${wechat.cp.appConfig.agentId}")
    private Integer agentId;

    @Override
    public boolean sendTextMessageToUser(String userId, String content) throws WxErrorException {
        WxCpMessage message = WxCpMessage.TEXT()
                .agentId(agentId)
                .toUser(userId)
                .content(content)
                .build();
        return sendMessage(message);
    }

    @Override
    public boolean sendTextMessageToUsers(String[] userIds, String content) throws WxErrorException {
        String toUsers = Arrays.stream(userIds)
                .collect(Collectors.joining("|"));
        WxCpMessage message = WxCpMessage.TEXT()
                .agentId(agentId)
                .toUser(toUsers)
                .content(content)
                .build();
        return sendMessage(message);
    }

    @Override
    public boolean sendTextMessageToParty(Integer partyId, String content) throws WxErrorException {
        WxCpMessage message = WxCpMessage.TEXT()
                .agentId(agentId)
                .toParty(partyId.toString())
                .content(content)
                .build();
        return sendMessage(message);
    }

    @Override
    public boolean sendMarkdownMessageToUser(String userId, String content) throws WxErrorException {
        WxCpMessage message = WxCpMessage.MARKDOWN()
                .agentId(agentId)
                .toUser(userId)
                .content(content)
                .build();
        return sendMessage(message);
    }

    @Override
    public boolean sendMarkdownMessageToUsers(String[] userIds, String content) throws WxErrorException {
        String toUsers = Arrays.stream(userIds)
                .collect(Collectors.joining("|"));
        WxCpMessage message = WxCpMessage.MARKDOWN()
                .agentId(agentId)
                .toUser(toUsers)
                .content(content)
                .build();
        return sendMessage(message);
    }

    @Override
    public boolean sendNewsMessageToUser(String userId, List<NewArticle> articles) throws WxErrorException {
        // 过滤掉无效的文章对象并限制数量
        List<NewArticle> validArticles = filterAndLimitArticles(articles);
        
        if (CollectionUtils.isEmpty(validArticles)) {
            log.warn("没有有效的文章对象可以发送");
            return false;
        }
        
        WxCpMessage message = WxCpMessage.NEWS()
                .agentId(agentId)
                .toUser(userId)
                .articles(validArticles)
                .build();
        return sendMessage(message);
    }

    @Override
    public boolean sendNewsMessageToUsers(String[] userIds, List<NewArticle> articles) throws WxErrorException {
        // 过滤掉无效的文章对象并限制数量
        List<NewArticle> validArticles = filterAndLimitArticles(articles);
        
        if (CollectionUtils.isEmpty(validArticles)) {
            log.warn("没有有效的文章对象可以发送");
            return false;
        }
        
        String toUsers = Arrays.stream(userIds)
                .collect(Collectors.joining("|"));
        WxCpMessage message = WxCpMessage.NEWS()
                .agentId(agentId)
                .toUser(toUsers)
                .articles(validArticles)
                .build();
        return sendMessage(message);
    }

    @Override
    public boolean sendLinkMessageToUser(String userId, String title, String description, String url, String picUrl) throws WxErrorException {
        NewArticle article = new NewArticle();
        article.setTitle(title != null ? title : "");
        article.setDescription(description != null ? description : "");
        article.setUrl(url != null ? url : "");
        article.setPicUrl(picUrl != null ? picUrl : "");
        
        return sendNewsMessageToUser(userId, Arrays.asList(article));
    }

    @Override
    public boolean sendMessage(WxCpMessage message) throws WxErrorException {
        try {
            wxCpService.getMessageService().send(message);
            log.info("企业微信消息发送成功: {}", message.toJson());
            return true;
        } catch (WxErrorException e) {
            log.error("企业微信消息发送失败: {}", e.getMessage(), e);
            throw e;
        }
    }
    
    /**
     * 过滤掉无效的文章对象并限制数量
     * 企业微信限制：图文消息的文章数量不能超过8条
     * 
     * @param articles 文章对象列表
     * @return 有效的文章对象列表（最多8条）
     */
    private List<NewArticle> filterAndLimitArticles(List<NewArticle> articles) {
        if (CollectionUtils.isEmpty(articles)) {
            return new ArrayList<>();
        }
        
        // 先过滤掉无效的文章对象
        List<NewArticle> validArticles = articles.stream()
                .filter(article -> article != null)
                .filter(article -> article.getTitle() != null && !article.getTitle().isEmpty())
                .filter(article -> article.getDescription() != null && !article.getDescription().isEmpty())
                .filter(article -> article.getUrl() != null && !article.getUrl().isEmpty())
                .filter(article -> article.getPicUrl() != null && !article.getPicUrl().isEmpty())
                .collect(Collectors.toList());
        
        // 再限制数量为8条以内
        if (validArticles.size() > 8) {
            log.warn("文章数量超过企业微信限制（8条），已自动截取前8条");
            validArticles = validArticles.subList(0, 8);
        }
        
        return validArticles;
    }
}